﻿using IntegratedOnBordDebug.UDPSocket;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Windows.Forms;

namespace IntegratedOnBordDebug
{
    public partial class FormMain : Form
    {
        public object objLock = new object();
        private static object objShowLock = new object();
        private CPPBox box = null;
        private bool FontUpdated = false;   //显示控制一体机字库下载完成标志
        private bool BoardProgramUpdated = false; //显示控制一体机下载完成标志
        private List<InfoDevices> listDevs = new List<InfoDevices>();
        private List<System.Net.IPEndPoint> listIPs = new List<System.Net.IPEndPoint>();

        public FormMain()
        {
            InitializeComponent();

            cbox_ipAddressLocal.DataSource = Common.GetHostIPv4List();

            this.FormClosing += Form1_FormClosing;
            cbox_BandRate.SelectedIndex = 0;
            cbox_ledType.SelectedIndex = 0;
            cbox_voiceType.SelectedIndex = 0;
            cbox_leftType.SelectedIndex = 0;
            comboBox_insertDateTime1.SelectedIndex = 0;
            comboBox_insertDateTime2.SelectedIndex = 0;
            comboBox_insertDateTime3.SelectedIndex = 0;
            comboBox_insertDateTime4.SelectedIndex = 0;

            cBox_Effect1.SelectedIndex = 0;
            cBox_Effect2.SelectedIndex = 0;
            cBox_Effect3.SelectedIndex = 0;
            cBox_Effect4.SelectedIndex = 0;

            comboBox_VolumeLevel.SelectedIndex = 6;
            comboBox_VolumeMale.SelectedIndex = 0;

            groupBox_bigFont.Enabled = checkBox_lineBindEnable.Checked;

            groupBox_timePos1.Enabled = checkBox_showDateTime1.Checked;
            groupBox_timePos2.Enabled = checkBox_showDateTime2.Checked;
            groupBox_timePos3.Enabled = checkBox_showDateTime3.Checked;
            groupBox_timePos4.Enabled = checkBox_showDateTime4.Checked;

            ContextMenu StatusRightMenu = new ContextMenu();
            MenuItem mClear = new MenuItem("清空", new EventHandler(StatusClearEvent));
            StatusRightMenu.MenuItems.Add(mClear);
            richtb_center_status.ContextMenu = StatusRightMenu;

            Text += string.Format(" V{0}", Application.ProductVersion);

            cbox_guidLed_color.SelectedIndex = 0;
            cbox_guidLed_showWay.SelectedIndex = 0;
        }

        private string GetStringData(byte[] data, string code)
        {
            string user = BitConverter.ToString(data);
            user = user.Replace("-00", "");
            string temp3 = "%" + user.Replace("-", "%");
            return HttpUtility.UrlDecode(temp3, Encoding.GetEncoding(code));

        }

        public uint GetUintData(byte[] data)
        {
            return BitConverter.ToUInt32(data, 0);
        }

        public int GetIntData(byte[] data)
        {
            return BitConverter.ToInt32(data, 0);
        }

        private InfoDevices GetModelFromData(byte[] data)
        {
            InfoDevices dev = new InfoDevices();
            MemoryStream ms = new MemoryStream(data);
            BinaryReader br = new BinaryReader(ms);

            byte[] b1 = br.ReadBytes(4);
            uint uVersion = BitConverter.ToUInt32(b1, 0);

            byte[] b11 = br.ReadBytes(4);
            uint uCommandId = BitConverter.ToUInt32(b11, 0);


            byte[] b2 = br.ReadBytes(4);
            uint uSessionId = BitConverter.ToUInt32(b2, 0);

            byte[] b3 = br.ReadBytes(4);
            uint uDataLength = BitConverter.ToUInt32(b3, 0);

            byte[] b4 = br.ReadBytes(4);
            uint uErrorCode = BitConverter.ToUInt32(b4, 0);

            byte[] bLeft = br.ReadBytes(8);

            byte[] b6 = br.ReadBytes(4);
            uint uCheckSum = BitConverter.ToUInt32(b6, 0);

            //设备名称
            byte[] bname = br.ReadBytes(32);
            string szName = GetStringData(bname, "GB2312");//HttpUtility.UrlDecode(str2, Encoding.GetEncoding("GB2312"));
            dev.SzName = szName;
            //用户名
            byte[] buser = br.ReadBytes(32);
            string szUser = GetStringData(buser, "GB2312");
            dev.SzUser = szUser;
            //用户密码
            byte[] bpwd = br.ReadBytes(32);
            string szPassword = GetStringData(bpwd, "GB2312");
            dev.SzPassword = szPassword;
            //生产厂商
            byte[] bfacturer = br.ReadBytes(32);
            string szManufacturer = GetStringData(bfacturer, "GB2312");
            dev.SzManufacturer = szManufacturer;
            //设备类型
            byte[] bdevType = br.ReadBytes(4);
            int uDeviceType = GetIntData(bdevType);
            dev.DeviceTypeName = Enum.GetName(typeof(InfoEnumClass.EmDeviceType), uDeviceType);
            dev.UDeviceType = uDeviceType;//Enum.Parse(typeof(InfoEnumClass.EmDeviceType), uDeviceType.ToString()).ToString();
                                          //设备能力集
            byte[] bability = br.ReadBytes(4);
            int uCapability = GetIntData(bability);
            dev.UCapability = uCapability;
            //生产日期
            byte[] bdate = br.ReadBytes(4);
            int uProductDate = GetIntData(bdate);
            dev.UProductDate = new DateTime(1970, 1, 1, 8, 0, 0).AddSeconds(uProductDate);
            //产品序列号
            byte[] bproductSN = br.ReadBytes(4);
            int uProductSn = GetIntData(bproductSN);
            dev.UProductSn = uProductSn.ToString();
            //软件版本
            byte[] bsoftVer = br.ReadBytes(4);
            int uSoftVersion = GetIntData(bsoftVer);
            dev.USoftVersion = GetHardVer(uSoftVersion);
            //硬件版本
            byte[] bhardVer = br.ReadBytes(4);
            int uHardVersion = GetIntData(bhardVer);
            dev.UHardVersion = GetHardVer(uHardVersion);
            //算法版本
            byte[] bAlgVersion = br.ReadBytes(4);
            int uAlgVersion = GetIntData(bAlgVersion);
            dev.UAlgVersion = GetHardVer(uAlgVersion);

            //车位数
            byte[] bvideoNum = br.ReadBytes(4);
            int uVideoChannelNum = GetIntData(bvideoNum);
            dev.UVideoChannelNum = uVideoChannelNum;
            //音频通道数
            byte[] uAudioChannelNum = br.ReadBytes(4);
            //解码通道数
            byte[] bdecodeNum = br.ReadBytes(4);
            int uDecodeChannelNum = GetIntData(bdecodeNum);
            dev.UDecodeChannelNum = uDecodeChannelNum;
            //I/O报警通道数
            byte[] uIOChannelNum = br.ReadBytes(4);
            //串口数
            byte[] uSerialNum = br.ReadBytes(4);
            //DHCP开关  0-关 1-开
            byte[] uDhcp = br.ReadBytes(4);
            dev.UDhcp = GetIntData(uDhcp);
            //中心服务器IP
            byte[] bserverIP = br.ReadBytes(4);
            uint uServerIp = GetUintData(bserverIP);
            dev.UServerIp = new System.Net.IPAddress(uServerIp).ToString();

            //中心服务器端口号
            byte[] bserverPort = br.ReadBytes(4);
            int uServerPort = GetIntData(bserverPort);
            dev.UServerPort = uServerPort;
            //设备IP
            byte[] baddrIP = br.ReadBytes(4);
            uint uIpv4Addr = GetUintData(baddrIP);
            dev.UIpv4Addr = new System.Net.IPAddress(uIpv4Addr).ToString();
            //子网掩码
            byte[] baddrMask = br.ReadBytes(4);
            uint uIpv4Mask = GetUintData(baddrMask);
            dev.UIpv4Mask = new System.Net.IPAddress(uIpv4Mask).ToString();
            //网关
            byte[] baddrGateway = br.ReadBytes(4);
            uint uIpv4Gateway = GetUintData(baddrGateway);
            dev.UIpv4Gateway = new System.Net.IPAddress(uIpv4Gateway).ToString();
            //DNS
            byte[] baddrDns = br.ReadBytes(4);
            uint uIpv4Dns = GetUintData(baddrDns);
            dev.UIpv4Dns = new System.Net.IPAddress(uIpv4Dns).ToString();
            //MAC
            byte[] baddrMac = br.ReadBytes(6);
            string byMac = BitConverter.ToString(baddrMac);
            dev.ByMac = byMac.Replace('-', ':');
            br.Close();
            ms.Close();
            ms.Dispose();
            return dev;
        }

        private void AsynUdp_DataRcvd(byte[] DData, System.Net.IPEndPoint iepRemote)
        {
            Task.Factory.StartNew(delegate
            {

                int idx = 32; //消息头默认长度
                byte[] tempData;
                string tmpStr = "";
                byte[] receiveData = DData;
                //Common.Log(string.Format("receive from {0} data : {1}", iepRemote.Address.ToString(), Common.BytesToHex(receiveData)));
#if Debug
                if (receiveData.Length >= 498)    //过滤其他设备
                {
                    InfoDevices dev = GetModelFromData(receiveData);

                    if (listDevs.Contains(dev) == false)
                    {
                        dev.ID = listDevs.Count() + 1;
                        listDevs.Add(dev);
                    }

                    showRecvData(string.Format("device: MAC {0},IPV4 {1}, ID {2}", dev.ByMac, dev.UIpv4Addr, dev.ID));
                    return;
                }
#endif
                if (receiveData.Length >= 32)
                {
                    //string ctype = receiveData[160].ToString();
                    InfoEnumClass.EmCommandID devInfo = GetContentData(receiveData);
                    try
                    {

                        switch (devInfo)
                        {
                            case InfoEnumClass.EmCommandID.CMD_PARK_READ_RFID:
                                objICCardInfo info = new objICCardInfo();
                                info.FromDevice = 1;
                                info.Ipv4 = iepRemote.Address.ToString();
                                if (info.ParseDataToModel(receiveData.Skip(idx).ToArray(),false))
                                {
                                    tmpStr = string.Format("收到 {0} 读IC卡 消息：卡号 {1}，", iepRemote,info.RFIDCardNo,info.InnerNo,info.PlateNum,info.ExtData);
                                    showRecvData(tmpStr);
                                }
                                break;
                            case InfoEnumClass.EmCommandID.CMD_PARK_SET_SUBSCRIBE:    //确认帮助请求
                                tmpStr = string.Format("已订阅设备 {0} 消息.", iepRemote);
                                showRecvData(tmpStr);
                                break;
                            case InfoEnumClass.EmCommandID.CMD_PARK_R_HELP:    //确认帮助请求
                                tmpStr = string.Format("收到设备 {0} 帮助请求.", iepRemote);
                                showRecvData(tmpStr);
                                break;
                            case InfoEnumClass.EmCommandID.CMD_PARK_T_HELP:    //确认帮助请求
                                tmpStr = string.Format("已确认设备 {0} 帮助请求.", iepRemote);
                                showRecvData(tmpStr);
                                break;
                            case InfoEnumClass.EmCommandID.CMD_PARK_RESET_SCANNER:    //扫码模块已重启
                                tmpStr = string.Format("设备 {0} 扫码模块已重启", iepRemote);
                                showRecvData(tmpStr);
                                break;
                            case InfoEnumClass.EmCommandID.CMD_PARK_R_AUTHORCODE:
                                tempData = receiveData.Skip(idx).ToArray();
                                tmpStr = Encoding.ASCII.GetString(tempData).Trim();
                                tmpStr = string.Format("收到设备 {0} 扫码 {1}", iepRemote, tmpStr);
                                showRecvData(tmpStr);
                                break;
                            case InfoEnumClass.EmCommandID.CMD_PARK_SET_GUID_LED:
                                tmpStr = string.Format("设备 {0} 收到引导屏设置指令.", iepRemote);
                                showRecvData(tmpStr);
                                break;
                            case InfoEnumClass.EmCommandID.CMD_PARK_SET_PROGRAM_UPDATE://回应远程升级指令
                                tmpStr = string.Format("设备 {0} 收到升级指令.", iepRemote);

                                break;
                            case InfoEnumClass.EmCommandID.CMD_PARK_SET_PROGRAM_DOWNLOAD: //远程下载程序回应
                                BoardProgramUpdated = true;
                                break;
                            case InfoEnumClass.EmCommandID.CMD_PARK_SET_CHARSLIB:    //回应字库下载命令
                                tmpStr = "字库已下载.";
                                FontUpdated = true;
                                showRecvData(tmpStr);
                                break;
                            case InfoEnumClass.EmCommandID.CMD_PARK_SET_BRAKE:
                                tmpStr = "设备闸杆控制命令已收到.";
                                showRecvData(tmpStr);
                                break;
                            case InfoEnumClass.EmCommandID.CMD_PARK_SET_VOICEBROADCAST:
                                tmpStr = "语音播报消息已收到.";
                                showRecvData(tmpStr);
                                break;
                            case InfoEnumClass.EmCommandID.CMD_BASIC_SET_SERIAL485:
                                tmpStr = "485串口信息已设置.";
                                showRecvData(tmpStr);
                                break;
                            case InfoEnumClass.EmCommandID.CMD_BASIC_SET_NETWORK:
                                tmpStr = "网络参数已设置.";
                                showRecvData(tmpStr);
                                break;
                            case InfoEnumClass.EmCommandID.CMD_BASIC_RECOVERY:
                                tmpStr = "已回复默认参数（网络）.";
                                showRecvData(tmpStr);
                                break;
                            case InfoEnumClass.EmCommandID.CMD_PARK_SET_LEDSWITCH:
                                tmpStr = "屏幕开闭已设置.";
                                showRecvData(tmpStr);
                                break;
                            case InfoEnumClass.EmCommandID.CMD_PARK_SET_EXTRA_LIGHT:
                                tmpStr = "补光灯已设置.";
                                showRecvData(tmpStr);
                                break;
                            case InfoEnumClass.EmCommandID.CMD_PARK_GET_EXTRA_LIGHT:    //回应查询补光灯开启和关闭时间
                                tmpStr = string.Format("补光灯状态：{0},开灯时间：{1},关灯时间：{2}", receiveData[idx] == 0x01 ? "定时生效" : "未定时", receiveData[idx + 1].ToString("D2") + ":" + receiveData[idx + 2].ToString("D2"), receiveData[idx + 3].ToString("D2") + ":" + receiveData[idx + 4].ToString("D2"));
                                showRecvData(tmpStr);
                                break;
                            case InfoEnumClass.EmCommandID.CMD_BASIC_SEARCHDEVICE:
                                tmpStr = string.Format("接收到设备 {0} 回应.", iepRemote);
                                this.Invoke((MethodInvoker)delegate { tb_ipAddress.Text = iepRemote.ToString(); tb_ipAddress.Text = tb_ipAddress.Text.Substring(0, tb_ipAddress.Text.IndexOf(':')); });

                                tempData = receiveData.Skip(idx).Take(4).ToArray();
                                tmpStr += "设备类型：" + BitConverter.ToInt32(tempData, 0).ToString();
                                idx += 4;
                                tempData = receiveData.Skip(idx).Take(4).Reverse().ToArray();
                                tmpStr += "，软件版本：" + GetHardVer(BitConverter.ToInt32(tempData, 0));
                                idx += 4;
                                tempData = receiveData.Skip(idx).Take(4).Reverse().ToArray();
                                tmpStr += "，硬件版本：" + GetHardVer(BitConverter.ToInt32(tempData, 0));
                                idx += 4;
                                tempData = receiveData.Skip(idx).Take(4).Reverse().ToArray();
                                tmpStr += "，IP 地址：" + string.Format("{0}.{1}.{2}.{3}", tempData[0], tempData[1], tempData[2], tempData[3]);
                                idx += 4;
                                tempData = receiveData.Skip(idx).Take(4).Reverse().ToArray();
                                tmpStr += "，子网掩码：" + string.Format("{0}.{1}.{2}.{3}", tempData[0], tempData[1], tempData[2], tempData[3]);
                                idx += 4;
                                tempData = receiveData.Skip(idx).Take(4).Reverse().ToArray();
                                tmpStr += "，网关：" + string.Format("{0}.{1}.{2}.{3}", tempData[0], tempData[1], tempData[2], tempData[3]);
                                idx += 4;
                                tempData = receiveData.Skip(idx).Take(6).ToArray();
                                tmpStr += "，MAC：" + string.Format("{0}:{1}:{2}:{3}:{4}:{5}", Common.OneByteToHex(tempData[0]), Common.OneByteToHex(tempData[1]), Common.OneByteToHex(tempData[2]), Common.OneByteToHex(tempData[3]), Common.OneByteToHex(tempData[4]), Common.OneByteToHex(tempData[5]));

                                showRecvData(tmpStr);
                                break;
                            case InfoEnumClass.EmCommandID.CMD_BASIC_GET_SYSTEM:
                                this.Invoke((MethodInvoker)delegate
                                {
                                    //Ipv4的地址
                                    byte devType = receiveData[idx];
                                    ++idx;
                                    tempData = receiveData.Skip(idx).Take(4).Reverse().ToArray();
                                    tmpStr += "软件版本:" + BitConverter.ToUInt32(tempData, 0).ToString();
                                    idx += 4;
                                    tempData = receiveData.Skip(idx).Take(4).Reverse().ToArray();
                                    tmpStr += "硬件版本:" + BitConverter.ToUInt32(tempData, 0).ToString();
                                    showRecvData(tmpStr);
                                });
                                break;
                            case InfoEnumClass.EmCommandID.CMD_BASIC_GET_NETWORK:
                                this.Invoke((MethodInvoker)delegate
                                {
                                    if (receiveData.Length > 32) //响应获取设备网络消息
                                    {
                                        //Ipv4的地址
                                        tempData = receiveData.Skip(idx).Take(4).Reverse().ToArray();
                                        string uIpv4Addr = string.Format("{0}.{1}.{2}.{3}", tempData[0], tempData[1], tempData[2], tempData[3]);
                                        tb_ipv4Addr.Text = uIpv4Addr;
                                        idx += 4;
                                        tempData = receiveData.Skip(idx).Take(4).Reverse().ToArray();
                                        string uIpv4Mask = string.Format("{0}.{1}.{2}.{3}", tempData[0], tempData[1], tempData[2], tempData[3]);
                                        tb_ipv4Mask.Text = uIpv4Mask;
                                        idx += 4;
                                        tempData = receiveData.Skip(idx).Take(4).Reverse().ToArray();
                                        string uIpv4Gateway = string.Format("{0}.{1}.{2}.{3}", tempData[0], tempData[1], tempData[2], tempData[3]);
                                        tb_ipv4Gate.Text = uIpv4Gateway;
                                        idx += 4;
                                        tempData = receiveData.Skip(idx).Take(6).ToArray();
                                        string byMac = string.Format("{0}:{1}:{2}:{3}:{4}:{5}", Common.OneByteToHex(tempData[0]), Common.OneByteToHex(tempData[1]), Common.OneByteToHex(tempData[2]), Common.OneByteToHex(tempData[3]), Common.OneByteToHex(tempData[4]), Common.OneByteToHex(tempData[5]));
                                        tb_deviceMac.Text = byMac;

                                        tmpStr = string.Format("IPv4地址 {0}，子网掩码 {1}，默认网关 {2}，MAC 地址 {3}", uIpv4Addr, uIpv4Mask, uIpv4Gateway, byMac);
                                        showRecvData(tmpStr);
                                    }
                                    else //回应
                                    {

                                    }
                                });
                                break;

                            case InfoEnumClass.EmCommandID.CMD_BASIC_SET_TIME://响应设置设备时间消息
                                tmpStr = "设备已校时.";
                                showRecvData(tmpStr);
                                break;
                            case InfoEnumClass.EmCommandID.CMD_BASIC_GET_TIME:    //响应获取设备时间消息
                                this.Invoke((MethodInvoker)delegate
                                {
                                    if (receiveData.Length > 32)
                                    {
                                        tempData = receiveData.Skip(idx).ToArray();
                                        tmpStr = string.Format("设备时间：{0}年{1}月{2}日{3}时{4}分{5}秒", "20" + tempData[0].ToString("D2"), tempData[1].ToString("D2"), tempData[2].ToString("D2"), tempData[3].ToString("D2"), tempData[4].ToString("D2"), tempData[5].ToString("D2"));
                                        showRecvData(tmpStr);
                                    }
                                    else //回应
                                    {

                                    }
                                });
                                break;
                            case InfoEnumClass.EmCommandID.CMD_BASIC_GET_SERIAL485:    //响应获取设备485串口消息
                                this.Invoke((MethodInvoker)delegate
                                {
                                    switch (receiveData[idx])
                                    {
                                        case 0x00:
                                            tmpStr = "波特率：4800";
                                            break;
                                        case 0x01:
                                            tmpStr = "波特率：9600";
                                            break;
                                        case 0x02:
                                            tmpStr = "波特率：19200";
                                            break;
                                        case 0x03:
                                            tmpStr = "波特率：57600";
                                            break;
                                        case 0x04:
                                            tmpStr = "波特率：115200";
                                            break;
                                    }
                                    showRecvData(tmpStr);
                                });
                                break;
                            case InfoEnumClass.EmCommandID.CMD_SET_LED_INFO:    //响应设置LED
                                this.Invoke((MethodInvoker)delegate
                                {
                                    if (receiveData.Length > 32)
                                    {
                                        byte cmdtype = receiveData[idx];
                                        if (cmdtype == 0x00)
                                        {
                                            /*
                                            00-16*64点阵屏
                                            01-32*64点阵屏
                                            02-32*128保留
                                            03-64*128点阵屏
                                            */
                                            switch (receiveData[++idx])
                                            {
                                                case 0x00:
                                                    tmpStr = "16*64点阵屏";
                                                    break;
                                                case 0x01:
                                                    tmpStr = "32*64点阵屏";
                                                    break;
                                                case 0x02:
                                                    tmpStr = "32*128点阵屏";
                                                    break;
                                                case 0x03:
                                                    tmpStr = "64*128点阵屏";
                                                    break;
                                            }
                                            showRecvData(tmpStr);
                                        }
                                    }
                                    else
                                    {
                                        showRecvData("显示屏设置成功！");
                                    }

                                });
                                break;
                        }
                    }
                    catch (Exception ex)
                    {
                        Common.Log(string.Format("LED设置失败：{0}\r\n{1}", ex.Message, ex.StackTrace), true);
                    }

                }
            });
        }

        /// <summary>
        /// 版本号进行2进制转10进制
        /// </summary>
        /// <param name="pBaseVer"></param>
        /// <returns></returns>
        public static string GetHardVer(int pBaseVer)
        {
            string t = Convert.ToString(pBaseVer, 2);
            string strBase = Convert.ToString(pBaseVer, 2).PadLeft(32, '0');
            string binA = strBase.Substring(0, 8);
            string binB = strBase.Substring(8, 8);
            string binC = strBase.Substring(24, 8);
            int decA = Convert.ToInt16(binA, 2);
            int decB = Convert.ToInt16(binB, 2);
            int decC = Convert.ToInt16(binC, 2);
            return "v" + decA.ToString() + "." + decB.ToString() + "." + decC.ToString();
        }

        /// <summary>接收数据显示
        /// 
        /// </summary>
        /// <param name="PlanTxt"></param>
        private void showRecvData(string PlanTxt, bool RedShow = false)
        {
            Invoke((MethodInvoker)delegate
                   {
                       lock (objShowLock)
                       {
                           string txt = richtb_center_status.Text;
                           string newString = string.Format("{0}: {1}", DateTime.Now.ToString("HH:mm:ss fff"), PlanTxt);
                           if (txt.Length > 0)
                               richtb_center_status.AppendText("\n");
                           if (RedShow)
                               richtb_center_status.SelectionColor = Color.Red;
                           else
                               richtb_center_status.SelectionColor = Color.Blue;
                           richtb_center_status.AppendText(newString);
                           richtb_center_status.ScrollToCaret();
                           richtb_center_status.Refresh();
                       }
                   });
        }

        public void StatusClearEvent(object sender, EventArgs e)
        {
            Control ctrl = ((ContextMenu)((MenuItem)sender).Parent).SourceControl;
            if (ctrl != null && ctrl is RichTextBox)
            {
                ((RichTextBox)ctrl).Clear();
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (box != null)
            {
                box.UdpAsyncClient.OnDataReceived -= AsynUdp_DataRcvd;
            }
            if (fastUdp != null)
            {
                fastUdp.OnReceive -= AsynUdp_DataRcvd;
            }

        }

        private InfoEnumClass.EmCommandID GetContentData(byte[] data)
        {
            MemoryStream ms = new MemoryStream(data);
            BinaryReader br = new BinaryReader(ms);

            byte[] b1 = br.ReadBytes(4);
            uint uVersion = BitConverter.ToUInt32(b1, 0);

            byte[] b11 = br.ReadBytes(4);
            uint uCommandId = BitConverter.ToUInt32(b11, 0);


            byte[] b2 = br.ReadBytes(4);
            uint uSessionId = BitConverter.ToUInt32(b2, 0);

            byte[] b3 = br.ReadBytes(4);
            uint uDataLength = BitConverter.ToUInt32(b3, 0);

            byte[] b4 = br.ReadBytes(4);
            uint uErrorCode = BitConverter.ToUInt32(b4, 0);

            byte[] bLeft = br.ReadBytes(8);

            byte[] b6 = br.ReadBytes(4);
            uint uCheckSum = BitConverter.ToUInt32(b6, 0);
            ms.Close();
            ms.Dispose();

            return (InfoEnumClass.EmCommandID)Enum.Parse(typeof(InfoEnumClass.EmCommandID), uCommandId.ToString());
        }

        //设置语音播报信息
        private void btnSetVoice_Click(object sender, EventArgs e)
        {
            int byContentType = Convert.ToInt32(cbox_voiceType.SelectedIndex);
            int byVolume = Convert.ToInt32(comboBox_VolumeLevel.SelectedIndex);
            int byType = Convert.ToInt32(comboBox_VolumeMale.SelectedIndex);
            float fCharges = 0;
            if (textBox10.Text != string.Empty)
            {
                fCharges = Convert.ToSingle(textBox10.Text);
            }
            box.SendSetVoice(tb_ipAddress.Text, byContentType, byVolume, byType, fCharges);
            showRecvData("设置语音播报信息命令已发送！", true);
        }

        private int GetEffect(int comboIdx)
        {
            int eIdx = 0;
            switch (comboIdx)
            {
                case 1:
                    eIdx = 2;
                    break;
                case 2:
                    eIdx = 3;
                    break;
            }
            return eIdx;
        }

        //LED显示设置
        private void btnSetScreen_Click(object sender, EventArgs e)
        {
            try
            {
                int cmdType = 2;
                int enableTime1 = 0;
                int timePos1 = 0;
                int timeFormat1 = 0;
                int enableTime2 = 0;
                int timePos2 = 0;
                int timeFormat2 = 0;
                int enableTime3 = 0;
                int timePos3 = 0;
                int timeFormat3 = 0;
                int enableTime4 = 0;
                int timePos4 = 0;
                int timeFormat4 = 0;
                int effect1 = 0;
                int effect2 = 0;
                int effect3 = 0;
                int effect4 = 0;

                if (((Button)sender).Name == "btnSetScreen")
                {
                    cmdType = 2;
                }
                else
                {
                    cmdType = cbox_toFlash.Checked ? 3 : 4; //断电保存 3 断电不保存 4；
                }

                switch (cbox_ledType.SelectedIndex)
                {
                    case 0: //16*64
                        effect1 = GetEffect(cBox_Effect1.SelectedIndex);
                        if (checkBox_showDateTime1.Enabled)
                        {
                            enableTime1 = checkBox_showDateTime1.Checked ? 1 : 0;
                            timePos1 = radioBtn_timePosPre1.Checked ? 0 : 1;
                            timeFormat1 = comboBox_insertDateTime1.SelectedIndex;
                            box.SendSetLed16Ride64Show(tb_ipAddress.Text, (int)numericUpDown_keepTime.Value, (int)num_screenFreshSpeed1.Value, tb_screenMsg1.Text, cmdType, enableTime1, timePos1, timeFormat1, effect1);
                        }
                        else
                        {
                            box.SendSetLed16Ride64Show(tb_ipAddress.Text, (int)numericUpDown_keepTime.Value, (int)num_screenFreshSpeed1.Value, tb_screenMsg1.Text, cmdType);
                        }
                        break;
                    case 1: //32*64
                        effect1 = GetEffect(cBox_Effect1.SelectedIndex);
                        effect2 = GetEffect(cBox_Effect2.SelectedIndex);
                        enableTime1 = checkBox_showDateTime1.Checked ? 1 : 0;
                        timePos1 = radioBtn_timePosPre1.Checked ? 0 : 1;
                        timeFormat1 = comboBox_insertDateTime1.SelectedIndex;
                        enableTime2 = checkBox_showDateTime2.Checked ? 1 : 0;
                        timePos2 = radioBtn_timePosPre2.Checked ? 0 : 1;
                        timeFormat2 = comboBox_insertDateTime2.SelectedIndex;
                        box.SendSetLed32Ride64Show(tb_ipAddress.Text, (int)numericUpDown_keepTime.Value, (int)num_screenFreshSpeed1.Value, tb_screenMsg1.Text, tb_screenMsg2.Text, cmdType, enableTime1, timePos1, timeFormat1, enableTime2, timePos2, timeFormat2, effect1, effect2);
                        break;
                    case 2: //32*128 保留
                        break;
                    case 3: //64*128
                        effect1 = GetEffect(cBox_Effect1.SelectedIndex);
                        effect2 = GetEffect(cBox_Effect2.SelectedIndex);
                        effect3 = GetEffect(cBox_Effect3.SelectedIndex);
                        effect4 = GetEffect(cBox_Effect4.SelectedIndex);
                        enableTime1 = checkBox_showDateTime1.Checked ? 1 : 0;
                        timePos1 = radioBtn_timePosPre1.Checked ? 0 : 1;
                        timeFormat1 = comboBox_insertDateTime1.SelectedIndex;
                        enableTime2 = checkBox_showDateTime2.Checked ? 1 : 0;
                        timePos2 = radioBtn_timePosPre2.Checked ? 0 : 1;
                        timeFormat2 = comboBox_insertDateTime2.SelectedIndex;

                        if (checkBox_lineBindEnable.Checked == false)
                        {
                            enableTime3 = checkBox_showDateTime3.Checked ? 1 : 0;
                            timePos3 = radioBtn_timePosPre3.Checked ? 0 : 1;
                            timeFormat3 = comboBox_insertDateTime3.SelectedIndex;
                            enableTime4 = checkBox_showDateTime4.Checked ? 1 : 0;
                            timePos4 = radioBtn_timePosPre4.Checked ? 0 : 1;
                            timeFormat4 = comboBox_insertDateTime4.SelectedIndex;
                            box.SendSetLed64Ride128Show(tb_ipAddress.Text, (int)numericUpDown_keepTime.Value, (int)num_screenFreshSpeed1.Value, tb_screenMsg1.Text, tb_screenMsg2.Text, tb_screenMsg3.Text, tb_screenMsg4.Text, cmdType, 0, enableTime1, timePos1, timeFormat1, enableTime2, timePos2, timeFormat2, enableTime3, timePos3, timeFormat3, enableTime4, timePos4, timeFormat4, effect1, effect2, effect3, effect4);
                        }
                        else
                        {
                            int showWay = cbox_leftType.SelectedIndex + 2;
                            //box.SendSetLed64Ride128Show(tb_ipAddress.Text, (int)numericUpDown_keepTime.Value, (int)num_screenFreshSpeed1.Value, tb_screenMsg1.Text, tb_screenMsg2.Text, tb_leftBigFont.Text, tb_screenMsg4.Text, cmdType, showWay, enableTime1, timePos1, timeFormat1, enableTime2, timePos2, timeFormat2, enableTime3, timePos3, timeFormat3, enableTime4, timePos4, timeFormat4, effect1, effect2, effect3, effect4);
                            box.SendSetLed64Ride128Show(tb_ipAddress.Text, (int)numericUpDown_keepTime.Value, (int)num_screenFreshSpeed1.Value, tb_screenMsg1.Text, tb_screenMsg2.Text, tb_leftBigFont.Text, "", cmdType, showWay, enableTime1, timePos1, timeFormat1, enableTime2, timePos2, timeFormat2, enableTime3, timePos3, timeFormat3, enableTime4, timePos4, timeFormat4, effect1, effect2, effect3, effect4);
                        }
                        break;
                }
                //box.SendRestart(tb_ipAddress.Text.Trim());
                showRecvData("LED即时显示设置命令已发送！", true);
            }
            catch (Exception ex)
            {
                Common.Log(string.Format("LED即时显示设置失败：{0}\r\n{1}", ex.Message, ex.StackTrace), true);
            }

        }


        //校时
        private void btn_setDateTime_Click(object sender, EventArgs e)
        {
            box.SendSetDateTime(tb_ipAddress.Text.Trim(), DateTime.Now);
            showRecvData("设置设备时间命令已发送！", true);
        }

        //获取时间
        private void btn_getDateTime_Click(object sender, EventArgs e)
        {
            try
            {
                box.SendGetDateTime(tb_ipAddress.Text);
                showRecvData("获取时间命令已发送！", true);
            }
            catch (Exception ex)
            {
                Common.Log(string.Format("获取时间失败：{0}\r\n{1}", ex.Message, ex.StackTrace), true);
            }
        }

        //获取基本信息
        private void btn_getDevInfo_Click(object sender, EventArgs e)
        {
            box.SendGetDeviceInfo(tb_ipAddress.Text);
            showRecvData("获取基本信息命令已发送！", true);
        }

        //获取网络信息
        private void btn_getNetInfo_Click(object sender, EventArgs e)
        {
            box.SendGetDeviceNet(tb_ipAddress.Text);
            showRecvData("获取网络信息命令已发送！", true);
        }

        //设置网络信息
        private void btn_setNetInfo_Click(object sender, EventArgs e)
        {
            box.SendSetNetWork(tb_ipAddress.Text, tb_ipv4Addr.Text.Trim(), tb_ipv4Mask.Text.Trim(), tb_ipv4Gate.Text.Trim(), tb_deviceMac.Text.Trim());
            showRecvData("设置网络信息命令已发送！", true);
        }

        //重启设备
        private void btn_restart_Click(object sender, EventArgs e)
        {
            box.SendRestart(tb_ipAddress.Text);
            showRecvData("重启设备命令已发送！", true);
        }

        //获取485信息
        private void btn_get485Info_Click(object sender, EventArgs e)
        {
            box.SendUdpGetSerial485(tb_ipAddress.Text);
            showRecvData("获取485命令已发送！", true);
        }

        //设置485
        private void btn_set485_Click(object sender, EventArgs e)
        {
            if (cbox_BandRate.SelectedIndex >= 0)
            {
                box.SendSetSerial485(tb_ipAddress.Text, cbox_BandRate.SelectedIndex);
                showRecvData("设置485命令已发送！", true);
            }
            else
            {
                showRecvData("请选择波特率！", true);
            }
        }

        //补光灯设置
        private void btn_setExtralLight_Click(object sender, EventArgs e)
        {
            int hourOn = int.Parse(timePicker_on.Value.ToString("HH"));
            int minuteOn = timePicker_on.Value.Minute;
            int hourOff = int.Parse(timePicker_off.Value.ToString("HH"));
            int minuteOff = timePicker_off.Value.Minute;
            box.SendSetExtralLight(tb_ipAddress.Text, checkBox_light.Checked, hourOn, minuteOn, hourOff, minuteOff);
            showRecvData("补光灯设置命令已发送！", true);
        }

        //抬杆
        private void btn_setBarUp_Click(object sender, EventArgs e)
        {
            box.SendSetBrakeBar(tb_ipAddress.Text, 1);
            showRecvData("闸杆控制命令已发送！", true);
        }

        //落杆
        private void btn_setBarDown_Click(object sender, EventArgs e)
        {
            box.SendSetBrakeBar(tb_ipAddress.Text, 0);
            showRecvData("闸杆控制命令已发送！", true);
        }

        //设置屏类型
        private void btn_setLedRide_Click(object sender, EventArgs e)
        {
            if (cbox_ledType.SelectedIndex >= 0)
            {
                box.SendSetLedType(tb_ipAddress.Text, cbox_ledType.SelectedIndex);
                showRecvData("设置屏类型命令已发送！", true);
            }
            //box.su.onReceiveUdpMsg += Su_onReceiveUdpMsg;
        }

        //屏类型选择
        private void cbox_ledType_SelectedIndexChanged(object sender, EventArgs e)
        {
            switch (cbox_ledType.SelectedIndex)
            {
                case 0://0-16*64点阵屏
                    group_line1.Enabled = true;
                    group_line2.Enabled = false;
                    group_line3.Enabled = false;
                    group_line4.Enabled = false;

                    checkBox_lineBindEnable.Enabled = false;
                    //groupBox_bigFont.Enabled = false;
                    break;
                case 1://1-32*64点阵屏
                    group_line1.Enabled = true;
                    group_line2.Enabled = true;
                    group_line3.Enabled = false;
                    group_line4.Enabled = false;

                    checkBox_lineBindEnable.Enabled = false;
                    break;
                case 2: //2-32*128点阵屏
                    group_line1.Enabled = true;
                    group_line2.Enabled = true;
                    group_line3.Enabled = false;
                    group_line4.Enabled = false;

                    checkBox_lineBindEnable.Enabled = false;
                    break;
                case 3://64*128 点阵屏
                    group_line1.Enabled = true;
                    group_line2.Enabled = true;
                    group_line3.Enabled = true;
                    group_line4.Enabled = true;

                    checkBox_lineBindEnable.Enabled = true;

                    break;
            }

        }

        //搜索设备
        private void btn_searchDevice_Click(object sender, EventArgs e)
        {
            try
            {
                listDevs.Clear();
                box.SendSearchDevice();
                //asynUdp.SendData(new byte[] { 0xB6, 0x6B, 0xFF, 0xBB, 0x02, 0x00, 0x00, 0x00, 0xE7, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF });
                showRecvData("搜索设备命令已发送!", true);
            }
            catch (Exception ex)
            {
                showRecvData("搜索设备命令错误：" + ex.Message + "\r\n" + ex.StackTrace, true);
            }

        }

        //广播修改IP
        private void btn_editIP_brodcast_Click(object sender, EventArgs e)
        {

            try
            {
                box.SendEditIP(tb_ipv4Addr.Text, tb_ipv4Mask.Text.Trim(), tb_ipv4Gate.Text.Trim(), tb_deviceMac.Text.Trim());
                showRecvData("广播修改IP命令已发送！", true);
            }
            catch (Exception ex)
            {
                showRecvData("广播修改IP错误：" + ex.Message + "\r\n" + ex.StackTrace, true);
            }
        }

        //查询屏类型
        private void btn_checkLedRide_Click(object sender, EventArgs e)
        {
            //byte[] tmp = Encoding.ASCII.GetBytes(" ");
            //return;

            //decimal d = 20.5m;
            //showRecvData(((int)d).ToString("d"));
            //return;

            box.SendGetLedType(tb_ipAddress.Text.Trim());
            showRecvData("查询屏类型命令已发送！", true);
        }

        private void btn_startListen_Click(object sender, EventArgs e)
        {
            //try
            //{
            //    Button btnSelf = ((Button)sender);
            //    if (btnSelf.Text == "开启监听")
            //    {
            //        new Orekaria.Lib.P2P.BroadcastHelper(80);

            //        box = new CPPBox(cbox_ipAddressLocal.Text);
            //        box.UdpAsyncClient.OnDataReceived += AsynUdp_DataRcvd;
            //        cbox_ipAddressLocal.Enabled = false;
            //    }
            //    else
            //    {
            //        box.UdpAsyncClient.OnDataReceived -= AsynUdp_DataRcvd;
            //    }


            //   ((Button)sender).Enabled = false;
            //}
            //catch (Exception ex)
            //{
            //    showRecvData("开启监听失败：" + ex.Message + "\r\n" + ex.StackTrace, true);
            //}

            try
            {
                Button btnSelf = ((Button)sender);
                if (btnSelf.Text == "开启监听")
                {
                    box = CPPBox.Init(cbox_ipAddressLocal.Text);
                    box.UdpAsyncClient.OnDataReceived += AsynUdp_DataRcvd;
                    cbox_ipAddressLocal.Enabled = false;

                    numUpDown_subPort.Value = box.ListeningPort;
                    btnSelf.Text = "关闭监听";
                }
                else
                {
                    CPPBox.UnInit();
                    cbox_ipAddressLocal.Enabled = true;
                    box.UdpAsyncClient.OnDataReceived -= AsynUdp_DataRcvd;
                    btnSelf.Text = "开启监听";
                }
            }
            catch (Exception ex)
            {
                showRecvData("开启监听失败：" + ex.Message + "\r\n" + ex.StackTrace, true);
            }

        }

        // 64*128 是否合并三四行
        private void checkBox_lineBindEnable_CheckedChanged(object sender, EventArgs e)
        {
            groupBox_bigFont.Enabled = ((CheckBox)sender).Checked;
            group_line3.Enabled = !groupBox_bigFont.Enabled;
            group_line4.Enabled = !groupBox_bigFont.Enabled;

        }

        //并行显示日期时间
        private void checkBox_showdatetime1_CheckedChanged(object sender, EventArgs e)
        {
            bool flag = ((CheckBox)sender).Checked;
            groupBox_timePos1.Enabled = flag;
        }

        //第二行启用显示时间
        private void checkBox_showDateTime2_CheckedChanged(object sender, EventArgs e)
        {
            bool flag = ((CheckBox)sender).Checked;
            groupBox_timePos2.Enabled = flag;
        }

        //第三行启用显示时间
        private void checkBox_showDateTime3_CheckedChanged(object sender, EventArgs e)
        {
            bool flag = ((CheckBox)sender).Checked;
            groupBox_timePos3.Enabled = flag;
        }

        //第四行启用显示时间
        private void checkBox_showDateTime4_CheckedChanged(object sender, EventArgs e)
        {
            bool flag = ((CheckBox)sender).Checked;
            groupBox_timePos4.Enabled = flag;
        }

        //读取补光灯设置信息
        private void btn_getExtralLight_Click(object sender, EventArgs e)
        {
            box.SendGetExtralLight(tb_ipAddress.Text.Trim());
            showRecvData("查询补光灯开启和关闭时间指令已发送。", true);
        }

        private void btn_lightOnAll_Click(object sender, EventArgs e)
        {
            try
            {
                box.SetLedLightOnAll(tb_ipAddress.Text.Trim(), cbox_ledType.SelectedIndex);
                showRecvData("全屏点亮指令已发送。", true);
                //box.SetLedLightOnAll(tb_ipAddress.Text.Trim(), 0, 0);
                //Thread.Sleep(200);
                //box.SetLedLightOnAll(tb_ipAddress.Text.Trim(), 1, 0);
                //Thread.Sleep(200);
                //box.SetLedLightOnAll(tb_ipAddress.Text.Trim(), 3, 0);
            }
            catch (Exception ex)
            {
                showRecvData(string.Format("全亮命令异常：{0}\r\n{1}", ex.Message, ex.StackTrace), true);
            }
        }

        private void checkBox_Test_CheckedChanged(object sender, EventArgs e)
        {
            CheckBox cbox = (CheckBox)sender;
            if (cbox.Checked)
            {
                timer_test.Interval = (int)num_interval.Value;
                timer_test.Start();
            }
            else
            {
                timer_test.Stop();
            }
        }

        private void timer_test_Tick(object sender, EventArgs e)
        {
            if (box != null)
            {
                btnSetScreen.PerformClick();
            }
        }

        //重置
        private void btn_setDefault_Click(object sender, EventArgs e)
        {
            try
            {
                if (DialogResult.Cancel == MessageBox.Show("确定要恢复设备的默认参数嘛？", "重要提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question))
                {
                    return;
                }

                if (box.SendSetDefaultNet(tb_ipAddress.Text))
                {
                    showRecvData("恢复设备的默认参数命令已发送！", true);
                }
                else
                {
                    showRecvData("恢复设备的默认参数命令发送失败！", true);
                }

            }
            catch (Exception ex)
            {
                showRecvData("恢复设备的默认参数命令发送异常：" + ex.Message + "\r\n" + ex.StackTrace, true);
            }
        }

        //选择升级文件
        private void btn_chooseFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDlg = new OpenFileDialog();
            openFileDlg.Filter = "Bin(*.bin)|*.bin";
            if (DialogResult.OK == openFileDlg.ShowDialog())
            {
                textBox_fileName.Text = openFileDlg.FileName;
            }
        }

        private void btn_update_Click(object sender, EventArgs e)
        {
            picBox_loading.Visible = true;

            if (string.IsNullOrEmpty(textBox_fileName.Text))
            {
                SetMsg("* 请选择程序文件！", Color.Red);
                return;
            }

            if (!File.Exists(textBox_fileName.Text))
            {
                SetMsg("* 程序文件不存在！", Color.Red);
                return;
            }



            string path = textBox_fileName.Text;
            progressBar_state.Value = 1;

            try
            {
                #region 读取升级文件

                if (MessageBox.Show("为了确保正确升级请勿操作其他选项！", "注意", MessageBoxButtons.OKCancel) == DialogResult.OK)
                {
                    SetMsg("正在升级请稍等...", Color.Black, false);
                    //新线程内处理升级文件
                    Task.Factory.StartNew(delegate
                    {
                        FileStream fs = new FileStream(path, FileMode.Open);
                        try
                        {
                            if (fs.CanRead)
                            {
                                byte[] libBuff = new byte[fs.Length];
                                fs.Read(libBuff, 0, (int)fs.Length);
                                if (libBuff.Length == 0)
                                    return;

                                double len = libBuff.Length / 256.0;
                                int bagTotal = (int)Math.Ceiling(len);
                                byte[] tmpByte;
                                DateTime dtWorkOn;
                                TimeSpan ts;

                                DateTime dtOn = DateTime.Now;

                                Invoke((Action)delegate
                                {
                                    progressBar_state.Maximum = bagTotal - 1;
                                });


                                bool downFail = false;
                                for (int j = 0; j < bagTotal; j++)
                                {
                                    Common.Log(string.Format("发送程序升级包序号：{0}", j));
                                    tmpByte = libBuff.Skip(j * 256).Take(256).ToArray();
                                    box.DownLoadProgram(tb_ipAddress.Text.Trim(), (uint)(bagTotal - 1), (uint)j, tmpByte);  //下发程序包

                                    dtWorkOn = DateTime.Now;
                                    int retryTimes = 0;

                                    //Thread.Sleep(1000);

                                    while (true)    //等待下位机回应
                                    {
                                        if (BoardProgramUpdated == true)
                                        {
                                            Invoke((Action)delegate
                                            {
                                                double pct = Convert.ToDouble(j) / Convert.ToDouble((bagTotal - 1));
                                                lbl_num_pecent.Text = string.Format("{0}", pct.ToString("0%"));
                                                progressBar_state.Value = j;
                                            });
                                            break;
                                        }
                                        else
                                        {

                                            ts = (DateTime.Now - dtWorkOn);
                                            if (ts.TotalSeconds >= 3) //超过三秒未收到回应
                                            {
                                                dtWorkOn = DateTime.Now;
                                                Common.Log(string.Format("重发程序升级包序号：{0}", j));
                                                box.DownLoadProgram(tb_ipAddress.Text.Trim(), (uint)(bagTotal - 1), (uint)j, tmpByte);  //下发程序包
                                                ++retryTimes;
                                            }

                                            Thread.Sleep(100);
                                            if (BoardProgramUpdated == true)
                                            {
                                                Invoke((Action)delegate
                                                {
                                                    double pct = Convert.ToDouble(j) / Convert.ToDouble((bagTotal - 1));
                                                    lbl_num_pecent.Text = string.Format("{0}", pct.ToString("0%"));
                                                    progressBar_state.Value = j;
                                                });
                                                break;
                                            }

                                            if (retryTimes >= 3) //超过重发次数失败！
                                            {
                                                downFail = true;

                                                break;
                                            }
                                        }
                                    }

                                    BoardProgramUpdated = false; //当条下发程序包状态复位

                                    if (downFail) //下载失败
                                    {
                                        break;
                                    }
                                    else
                                    {

                                    }
                                }

                                if (downFail == false)
                                {
                                    box.SendRemoteUpdate(tb_ipAddress.Text.Trim(), (uint)libBuff.Length);
                                    Invoke((Action)delegate
                                    {
                                        SetMsg("升级成功！" + (DateTime.Now - dtOn).TotalSeconds.ToString(), Color.Green, true);
                                    });
                                }
                                else
                                {
                                    Invoke((Action)delegate
                                    {
                                        SetMsg("升级失败！" + (DateTime.Now - dtOn).TotalSeconds.ToString(), Color.Red, true);
                                    });
                                }

                            }
                            fs.Close();
                            fs.Dispose();

                        }
                        catch (Exception ex)
                        {
                            SetMsg(string.Format("程序升级失败：{0}", ex.Message), Color.Red, true);
                            Common.Log(string.Format("程序升级失败：{0}\r\n{1}", ex.Message, ex.StackTrace));
                        }
                        finally
                        {
                            fs.Close();
                            fs.Dispose();
                            GC.Collect();
                            Invoke((Action)delegate
                            {
                                btn_update.Enabled = true;
                            });
                        }
                    });
                }

                #endregion
            }
            catch (Exception ex)
            {
                btn_update.Enabled = true;
                SetMsg(ex.Message, Color.Red);
                Common.Log("程序升级异常：" + ex.Message + "\r\n" + ex.StackTrace, true);
            }

        }

        /// <summary>提示信息设置
        /// 
        /// </summary>
        /// <param name="msg">信息内容</param>
        /// <param name="icolor">文字颜色</param>
        /// <param name="needCrossThread">是否跨线程 true 是，false 不是（默认）</param>
        private void SetMsg(string msg, Color icolor, bool needCrossThread = false)
        {
            if (!needCrossThread)
            {
                lbl_state.ForeColor = icolor;
                lbl_state.Text = msg;
            }
            else
            {
                Invoke((Action)delegate
                {
                    lbl_state.ForeColor = icolor;
                    lbl_state.Text = msg;
                });
            }
        }

        /// <summary>提示信息设置
        /// 
        /// </summary>
        /// <param name="msg">信息内容</param>
        /// <param name="icolor">文字颜色</param>
        /// <param name="needCrossThread">是否跨线程 true 是，false 不是（默认）</param>
        private void SetMsgFontLib(string msg, Color icolor, bool needCrossThread = false)
        {
            if (!needCrossThread)
            {
                lbl_state_fontlib.ForeColor = icolor;
                lbl_state_fontlib.Text = msg;
            }
            else
            {
                Invoke((Action)delegate
                {
                    lbl_state_fontlib.ForeColor = icolor;
                    lbl_state_fontlib.Text = msg;
                });
            }
        }

        private void btn_chooseFontLib_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDlg = new OpenFileDialog();
            openFileDlg.Filter = "Bin(*.bin)|*.bin";
            if (DialogResult.OK == openFileDlg.ShowDialog())
            {
                tb_fontLib_fileName.Text = openFileDlg.FileName;
            }
        }

        private void btn_update_fontlib_Click(object sender, EventArgs e)
        {
            picBox_loading_fontLib.Visible = true;

            if (string.IsNullOrEmpty(tb_fontLib_fileName.Text))
            {
                SetMsgFontLib("* 请选择字库文件！", Color.Red);
                return;
            }

            if (!File.Exists(tb_fontLib_fileName.Text))
            {
                SetMsgFontLib("* 字库不存在！", Color.Red);
                return;
            }



            string path = tb_fontLib_fileName.Text;
            progressBar_state.Value = 1;

            try
            {
                #region 读取升级文件

                if (MessageBox.Show("为了确保正确下载字库请勿操作其他选项！", "注意", MessageBoxButtons.OKCancel) == DialogResult.OK)
                {
                    SetMsgFontLib("正在下载字库请稍等...", Color.Black, false);
                    //新线程内处理升级文件
                    Task.Factory.StartNew(delegate
                    {
                        FileStream fs = new FileStream(path, FileMode.Open);
                        try
                        {
                            if (fs.CanRead)
                            {
                                byte[] libBuff = new byte[fs.Length];
                                fs.Read(libBuff, 0, (int)fs.Length);
                                if (libBuff.Length == 0)
                                    return;

                                double len = libBuff.Length / 256.0;
                                int bagTotal = (int)Math.Ceiling(len);
                                byte[] tmpByte;
                                DateTime dtWorkOn;
                                TimeSpan ts;

                                Invoke((Action)delegate
                                {
                                    progressBar_state_fontlib.Maximum = bagTotal - 1;
                                });


                                bool downFail = false;
                                for (int j = 0; j < bagTotal; j++)
                                {
                                    Common.Log(string.Format("发送字库包序号：{0}", j));
                                    tmpByte = libBuff.Skip(j * 256).Take(256).ToArray();
                                    box.DownLoadFontLibByUdp(tb_ipAddress.Text.Trim(), (uint)(bagTotal - 1), (uint)j, tmpByte);  //下发程序包

                                    dtWorkOn = DateTime.Now;
                                    int retryTimes = 0;

                                    //Thread.Sleep(1000);

                                    while (true)    //等待下位机回应
                                    {
                                        if (FontUpdated == true)
                                        {
                                            Invoke((Action)delegate
                                            {
                                                double pct = Convert.ToDouble(j) / Convert.ToDouble((bagTotal - 1));
                                                lbl_num_pecentFontLib.Text = string.Format("{0}", pct.ToString("0%"));
                                                progressBar_state_fontlib.Value = j;
                                            });
                                            break;
                                        }
                                        else
                                        {

                                            ts = (DateTime.Now - dtWorkOn);
                                            if (ts.TotalSeconds >= 3) //超过三秒未收到回应
                                            {
                                                dtWorkOn = DateTime.Now;
                                                Common.Log(string.Format("重发字库包序号：{0}", j));
                                                box.DownLoadFontLibByUdp(tb_ipAddress.Text.Trim(), (uint)(bagTotal - 1), (uint)j, tmpByte);  //下发程序包
                                                ++retryTimes;
                                            }

                                            Thread.Sleep(100);
                                            if (FontUpdated == true)
                                            {
                                                Invoke((Action)delegate
                                                {
                                                    double pct = Convert.ToDouble(j) / Convert.ToDouble((bagTotal - 1));
                                                    lbl_num_pecentFontLib.Text = string.Format("{0}", pct.ToString("0%"));
                                                    progressBar_state_fontlib.Value = j;
                                                });
                                                break;
                                            }

                                            if (retryTimes >= 3) //超过重发次数失败！
                                            {
                                                downFail = true;

                                                break;
                                            }
                                        }
                                    }

                                    FontUpdated = false; //当条下发程序包状态复位

                                    if (downFail) //下载失败
                                    {
                                        break;
                                    }
                                    else
                                    {

                                    }
                                }

                                if (downFail == false)
                                {
                                    box.SendRemoteUpdate(tb_ipAddress.Text.Trim(), (uint)libBuff.Length);
                                    Invoke((Action)delegate
                                    {
                                        SetMsgFontLib("字库下载成功！", Color.Green, true);
                                    });
                                }
                                else
                                {
                                    Invoke((Action)delegate
                                    {
                                        SetMsgFontLib("字库下载失败！", Color.Red, true);
                                    });
                                }

                            }
                            fs.Close();
                            fs.Dispose();

                        }
                        catch (Exception ex)
                        {
                            SetMsgFontLib(string.Format("字库下载失败：{0}", ex.Message), Color.Red, true);
                            Common.Log(string.Format("字库下载失败：{0}\r\n{1}", ex.Message, ex.StackTrace));
                        }
                        finally
                        {
                            fs.Close();
                            fs.Dispose();
                            GC.Collect();
                            Invoke((Action)delegate
                            {
                                btn_update_fontlib.Enabled = true;
                            });
                        }
                    });
                }

                #endregion
            }
            catch (Exception ex)
            {
                btn_update_fontlib.Enabled = true;
                SetMsg(ex.Message, Color.Red);
                Common.Log("字库升级异常：" + ex.Message + "\r\n" + ex.StackTrace, true);
            }
        }

        //关闭屏幕指令
        private void btn_lightSwitch_Click(object sender, EventArgs e)
        {

            bool flag = Convert.ToBoolean(btn_lightSwitch.Tag);
            box.SendSetLedOnOff(tb_ipAddress.Text.Trim(), flag);
            btn_lightSwitch.Tag = !flag;
            btn_lightSwitch.Text = flag ? "关闭频幕" : "开启屏幕";
            btn_lightSwitch.Refresh();
            SetMsg("屏幕开闭命令已发送.", Color.Black);
        }

        private void btnSetVoice_mall_Click(object sender, EventArgs e)
        {
            int byContentType = Convert.ToInt32(cbox_voiceType.SelectedIndex);
            int byVolume = Convert.ToInt32(comboBox_VolumeLevel.SelectedIndex);
            int byType = Convert.ToInt32(comboBox_VolumeMale.SelectedIndex);
            float fCharges = 0;
            if (textBox10.Text != string.Empty)
            {
                fCharges = Convert.ToSingle(textBox10.Text);
            }
            int split = (int)num_voiceSplit.Value;

            Task.Factory.StartNew(delegate
            {
                box.SendSetVoice(tb_ipAddress.Text, 0, byVolume, byType, fCharges);
                Thread.Sleep(split);
                box.SendSetVoice(tb_ipAddress.Text, 1, byVolume, byType, fCharges);
                Thread.Sleep(split);
                box.SendSetVoice(tb_ipAddress.Text, 2, byVolume, byType, fCharges);
                Thread.Sleep(split);
                box.SendSetVoice(tb_ipAddress.Text, 3, byVolume, byType, fCharges);
                Thread.Sleep(split);
                box.SendSetVoice(tb_ipAddress.Text, 4, byVolume, byType, fCharges);
                Thread.Sleep(split);
                box.SendSetVoice(tb_ipAddress.Text, 5, byVolume, byType, fCharges);
                showRecvData("设置语音连续播报信息命令已发送！", true);
            });


        }


        FastUdpSocketLockQueue fastUdp = null;
        UDPIOCP.UdpServer server = null;


        private void btn_udpiocp_listen_Click(object sender, EventArgs e)
        {
            ((Button)sender).Enabled = false;

            try
            {
                //server = new UDPIOCP.UdpServer(11000, 0, 10000);
                //server.OnReceivedData += Server_OnReceivedData;
                //server.Start();

                fastUdp = new FastUdpSocketLockQueue(11000, 1024);
                //fastUdp.OnReceive += AsynUdp_DataRcvd;
                fastUdp.OnBroadCastReceiveOver += FastUdp_OnBroadCast;
                fastUdp.Start();
            }
            catch (Exception ex)
            {
                showRecvData(string.Format("监听失败：{0}\r\n{1}", ex.Message, ex.StackTrace));
            }

        }

        private void FastUdp_OnBroadCast(object sender, List<byte[]> responseItems)
        {
            try
            {
                Application.DoEvents();
                //if (responseItems.Count > 0)
                //{
                //    for (int i = 0; i < responseItems.Count; i++)
                //    {
                //        if (responseItems[i].Length >= 498)    //过滤其他设备
                //        {
                //            InfoDevices dev = GetModelFromData(responseItems[i]);

                //            if (listDevs.Contains(dev) == false)
                //            {
                //                dev.ID = listDevs.Count() + 1;
                //                listDevs.Add(dev);
                //            }

                //            showRecvData(string.Format("device: MAC {0},IPV4 {1}, ID {2}", dev.ByMac, dev.UIpv4Addr, dev.ID));
                //        }
                //    }
                //}

                showRecvData(string.Format("devices sum " + responseItems.Count.ToString()));
            }
            catch (Exception ex)
            {
                showRecvData(string.Format("设备数据接收处理失败：{0}\r\n{1}", ex.Message, ex.StackTrace));
            }
        }

        private void Server_OnReceivedData(object sender, SocketAsyncEventArgs e)
        {
            Task.Factory.StartNew(delegate
            {
                try
                {
                    if (listIPs.Contains((IPEndPoint)e.RemoteEndPoint) == false)
                    {
                        listIPs.Add((IPEndPoint)e.RemoteEndPoint);
                    }

                    showRecvData(string.Format("received {0} {1} \r\n   ", ((IPEndPoint)e.RemoteEndPoint).Address, listIPs.Count, Common.BytesToHex(e.Buffer)));
                    //Common.Log(Common.BytesToHex(args));
                }
                catch (Exception ex)
                {
                    showRecvData(string.Format("数据接收处理失败：{0}\r\n{1}", ex.Message, ex.StackTrace));
                }

            });
        }

        public static object ucsLocker = new object();
        private void Ucs_ReceiveDataEvent(byte[] args, System.Net.IPEndPoint ipe)
        {
            Task.Factory.StartNew(delegate
            {
                try
                {
                    if (listIPs.Contains(ipe) == false)
                    {
                        listIPs.Add(ipe);
                    }
                    showRecvData(string.Format("received {0} {1} \r\n   ", ipe.Address, listIPs.Count, Common.BytesToHex(args)));
                    //Common.Log(Common.BytesToHex(args));
                }
                catch (Exception ex)
                {
                    showRecvData(string.Format("数据接收异常：{0}\r\n{1}", ex.Message, ex.StackTrace));
                }

            });

        }

        private void btn_iocp_search_Click(object sender, EventArgs e)
        {
            listIPs.Clear();
            listDevs.Clear();

            byte[] search = new byte[] { 0xB6, 0x6B, 0xFF, 0xBB, 0x02, 0x00, 0x00, 0x00, 0xE7, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0xC5, 0xB0, 0xB3 };
            IPEndPoint ipeRemote = new IPEndPoint(IPAddress.Broadcast, 80);
            //if (server != null)
            //{
            //    server.SendBrodCast(search);
            //}


            fastUdp?.SendTo(ipeRemote, search, true);

            newsock?.SendTo(search, ipeRemote);
        }



        Socket newsock = null;
        Task receiveTask = null;

        private void btn_testReceiveBrodcast_Click(object sender, EventArgs e)
        {
            if (newsock != null && receiveTask != null)
            {
                showRecvData("已启动监听.");
                return;
            }

            receiveTask = Task.Factory.StartNew(delegate
            {
                try
                {
                    int recv;
                    byte[] data = new byte[1024];
                    IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("192.168.0.249"), 9050);
                    newsock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                    newsock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                    newsock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
                    newsock.DontFragment = true;
                    newsock.EnableBroadcast = true;
                    newsock.Bind(ipep);
                    showRecvData("Waiting for a client...");
                    EndPoint Remote = new IPEndPoint(IPAddress.Any, 0);
                    while (true)
                    {
                        if (newsock.Available > 32)
                        {
                            data = new byte[500];
                            recv = newsock.ReceiveFrom(data, ref Remote);
                            showRecvData(string.Format("Receive from {0} data {1}", Remote == null ? "" : Remote.ToString(), Common.BytesToHex(data)));
                            Thread.Sleep(200);
                        }
                    }
                }
                catch (Exception ex)
                {
                    showRecvData(string.Format("Broadcast 监听失败：{0}\r\n{1}", ex.Message, ex.StackTrace));
                }

            });
        }

        private void btn_guidLed_set_Click(object sender, EventArgs e)
        {
            try
            {
                box.SendSetGuidLed(tb_ipAddress.Text, (int)num_LedId.Value, cbox_guidLed_color.SelectedIndex, cbox_guidLed_showWay.SelectedIndex, (int)num_showNum.Value);
                showRecvData("设置引导屏命令已发送！", true);
            }
            catch (Exception ex)
            {
                showRecvData("设置引导屏命令异常：" + ex.Message + "\r\n" + ex.StackTrace, true);
            }

        }

        //消息订阅
        private void btn_subscript_Click(object sender, EventArgs e)
        {
            try
            {
                box.SendSubscribe(tb_ipAddress.Text, cbox_ipAddressLocal.Text, (int)numUpDown_subPort.Value);
                showRecvData("扩展设备消息订阅指令已发送！", true);
            }
            catch (Exception ex)
            {
                showRecvData("扩展设备消息订阅指令异常：" + ex.Message + "\r\n" + ex.StackTrace, true);
            }
        }

        //重启扫码设备
        private void btn_resetScanner_Click(object sender, EventArgs e)
        {
            try
            {
                box.SendScannerReset(tb_ipAddress.Text);
                showRecvData("扫码模块重启指令已发送！", true);
            }
            catch (Exception ex)
            {
                showRecvData("扫码模块重启指令异常：" + ex.Message + "\r\n" + ex.StackTrace, true);
            }
        }

        private void btn_confirmHelp_Click(object sender, EventArgs e)
        {
            try
            {
                box.SendHelpAnswer(tb_ipAddress.Text);
                showRecvData("帮助按钮确认指令已发送！", true);
            }
            catch (Exception ex)
            {
                showRecvData("帮助按钮确认指令异常：" + ex.Message + "\r\n" + ex.StackTrace, true);
            }
        }
    }
}
